//
//  RoomViewController.m
//  baseVideo
//
//  Created by 盛锋 on 2019/5/23.
//  Copyright © 2019年 Elliot. All rights reserved.
//

#import "RoomViewController.h"
#import "Masonry.h"
#import "VideoViewRender.h"
#import "N2MSetting.h"
#import <CoreTelephony/CTCallCenter.h>
#import <CoreTelephony/CTCall.h>
#import "ViewController.h"
#import <avd_sdk/RTCAudioSession.h>
#import <ReplayKit/ReplayKit.h>

#warning all Delegate please Jump to Definition Demo只做了2人视频展示

@interface RoomViewController ()<AVDRoomDelegate,AVDVideoDelegate,AVDUserManagerDelegate,AVDAudioDelegate,AVDWhiteboardDelegate,AVDScreenDelegate,AVDChatDelegate>

@property (weak, nonatomic) IBOutlet UIView *navView;///<导航栏
@property (weak, nonatomic) IBOutlet UILabel *roomId;///<房间id
@property (weak, nonatomic) IBOutlet UIView *bottomTabBar;
@property (weak, nonatomic) AVDVideo *mvideo;///<视频模块
@property (weak, nonatomic) AVDAudio *maudio;///<音频模块
@property (weak, nonatomic) AVDUserManager *mmanager;///<用户管理模块
@property (strong, nonatomic) VideoViewRender *bigRender;///<大视频
@property (strong, nonatomic) VideoViewRender *smallRender;///<小视频
@property (weak, nonatomic) AVDScreen *mscreen;///<视频模块
@property (weak, nonatomic) AVDChat *mchat;///<聊天模块

@property (weak, nonatomic) AVDWhiteboard *mwhiteboard;///<白板模块
@property (strong, nonatomic) AVDCanvasView *boradView;///<白板view
@property (strong, nonatomic) AVDWhiteboardInfo *boradInfo;///<白板view

@property (assign, nonatomic) BOOL isSwitch;///<是否切换
@property (strong, nonatomic) CTCallCenter *callCenter;///<
@property (nonatomic, strong) AVAudioPlayer *audioPlayer; // 播放
@property (strong, nonatomic) UIView *topView;///<视频模块
@property (nonatomic,weak) RPSystemBroadcastPickerView *broadPickerView;

@end

@implementation RoomViewController{
    NSString *_localVideoId;
    NSString *_localScreenId;
}

- (void)viewDidLoad {
    [super viewDidLoad];
//    [self performSelector:@selector(closeRoom:) withObject:nil afterDelay:5];
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(publishScreenCallback:) name:  AVDRPScreenRecorderStartErrorNotification object:nil];
//    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(stopScreenErrCallback:) name:  AVDRPScreenRecorderStopErrorNotification object:nil];
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(uiChangeNotifi:) name:  UIDeviceOrientationDidChangeNotification object:nil];
 [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(willEnterForegroud:) name:  UIApplicationWillEnterForegroundNotification object:nil];
    [self setupUI];
    [self addUploaderEventMonitor];
    [self configRoom];
    [self subPublishedCamers];
    self.callCenter = [CTCallCenter new];
    __weak typeof(self) weakSelf = self;
   self.callCenter.callEventHandler = ^(CTCall *call) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if ([call.callState isEqualToString:CTCallStateDialing]) {
                NSLog(@"电话主动拨打电话");
            }  else if ([call.callState isEqualToString:CTCallStateDisconnected]) {
                NSLog(@"电话挂断");
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//                    [weakSelf.mscreen proceedRecord];
                });
//                sleep(0.5);
            } else if ([call.callState isEqualToString:CTCallStateIncoming] || [call.callState isEqualToString:CTCallStateConnected]) {
//                [weakSelf.mscreen stopRecord];
                NSLog(@"电话被叫 || 电话接通");
            } else {
            }
        });
    };
}

//布局
- (void)setupUI{
    UITapGestureRecognizer *reg = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showSDKLog)];
    [self.navView addGestureRecognizer:reg];
    //更新房间号
    self.roomId.text = [NSString stringWithFormat:@"房间号：%@",[self.room getRoomId]];
    UIView *superView = self.view;
//    superView.backgroundColor = [UIColor blackColor];
    //add bigRender
    self.bigRender = [[VideoViewRender alloc] init];
//    self.bigRender.backgroundColor = [UIColor greenColor];
    [self.view addSubview:self.bigRender];
   
    //add smallRender
    self.smallRender = [[VideoViewRender alloc] init];
    //self.smallRender.backgroundColor = [UIColor blueColor];
    [self.view addSubview:self.smallRender];
    [_smallRender addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(switchRender)]];
    
    self.boradView = [[AVDCanvasView alloc]init];
    self.boradView.hidden = YES;
    [_bigRender addSubview:self.boradView];
    
    //layout bigRender
    [_bigRender mas_makeConstraints:^(MASConstraintMaker *make) {
        make.right.left.equalTo(superView);
        make.top.equalTo(self.navView.mas_bottom);
        make.bottom.equalTo(self.bottomTabBar.mas_top);
    }];
    //layout smallRender
    [_smallRender mas_makeConstraints:^(MASConstraintMaker *make) {
        make.right.equalTo(superView.mas_right).offset(-8);
        make.bottom.equalTo(self.bottomTabBar.mas_top).offset(-8);
        make.size.mas_equalTo(CGSizeMake(100, 160));
    }];
    
    [_boradView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.right.left.equalTo(superView);
        make.top.equalTo(self.navView.mas_bottom);
        make.bottom.equalTo(self.bottomTabBar.mas_top);
    }];
    [self.view layoutIfNeeded];
    
    self.topView = [[UIView alloc]initWithFrame:superView.frame];
    self.topView.backgroundColor = [UIColor colorWithRed:0/255.0 green:90/255.0 blue:0 alpha:1];
    self.topView.hidden = YES;
    [self.view addSubview:self.topView];
   /* __block float time = 0.00f;
    NSTimer *timer = [NSTimer timerWithTimeInterval:0 repeats:YES block:^(NSTimer * _Nonnull timer) {
        time += 0.0001;
        self.roomId.text = [NSString stringWithFormat:@"%.3f",time];
    }];
    [timer fire];
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];*/
}

- (void)switchRender{
    UIView *superView = self.view;
    [_smallRender mas_remakeConstraints:^(MASConstraintMaker *make) {
        if (!self->_isSwitch) {
            make.right.left.equalTo(superView);
            make.top.equalTo(self.navView.mas_bottom);
            make.bottom.equalTo(self.bottomTabBar.mas_top);
        }else{
            make.right.equalTo(superView.mas_right).offset(-8);
            make.bottom.equalTo(self.bottomTabBar.mas_top).offset(-8);
            make.size.mas_equalTo(CGSizeMake(100, 160));
        }
    }];
    [_bigRender mas_remakeConstraints:^(MASConstraintMaker *make) {
        if (!self->_isSwitch) {
            make.right.equalTo(superView.mas_right).offset(-8);
            make.bottom.equalTo(self.bottomTabBar.mas_top).offset(-8);
            make.size.mas_equalTo(CGSizeMake(100, 160));
        }else{
            make.right.left.equalTo(superView);
            make.top.equalTo(self.navView.mas_bottom);
            make.bottom.equalTo(self.bottomTabBar.mas_top);
        }
    }];
    [self.view updateConstraintsIfNeeded];
    [self.view layoutIfNeeded];
    [self.view bringSubviewToFront:_isSwitch?_smallRender:_bigRender];
    _isSwitch = !_isSwitch;
}

//获取对于音视频模块 本demo只做简单音视频
- (void)configRoom{
    self.mvideo = [AVDVideo getVideo:self.room];//获取视频模块
    self.mvideo.delegate = self;//设置视频模块代理
    self.maudio = [AVDAudio getAudio:self.room];//获取音频模块
    self.maudio.delegate = self;//设置音频模块代理
    self.mmanager = [AVDUserManager getUserManager:self.room];//s获取用户管理模块
    self.mmanager.delegate = self;//设置用户管理回调
    self.room.delegate = self;//s设置房间代理
    self.mscreen = [AVDScreen getScreen:self.room];
    self.mscreen.delegate = self;
    self.mwhiteboard = [AVDWhiteboard getWhiteboard:self.room];
    self.mwhiteboard.delegate = self;
    self.mchat = [AVDChat getChat:self.room];
    self.mchat.delegate = self;
    if (self.mwhiteboard.sharedBoards.count) {
        self.boradInfo = self.mwhiteboard.sharedBoards.lastObject;
    }
    //默认发布音视频
    [self.mvideo publishLocalCamera];
    [self.maudio openMicrophone];
    CGFloat width = [UIScreen mainScreen].bounds.size.width;
    CGFloat height = [UIScreen mainScreen].bounds.size.height;
    NSLog(@"screen w = %d",width);
    [self.room enableStats:YES];
//    [self.mscreen publishScreen:0 catY:0 catW:width catH:height/2];
   // NSLog(@"audio mode = %d",[self.maudio getSpeakerMode]);
//    [self.mscreen publishScreen:screen_resolution_720p fps:15];
//    [self.room enableStats:YES];
}



//订阅已经发布的一个摄像头
- (void)subPublishedCamers{
    NSLog(@"current room cammera published count == %d",self.mvideo.publishedCameras.count);
    if (self.mvideo.publishedCameras.count>0) {
        __weak typeof(self) weakSelf = self;
        //获取已经发布的视频流列表
        [self.mvideo.publishedCameras enumerateObjectsUsingBlock:^(AVDCamera *camer, NSUInteger idx, BOOL * _Nonnull stop) {
            __strong typeof(weakSelf) strongSelf = weakSelf;
            if (![strongSelf.mvideo isSelfDevice:camer.id]) {//2人demo 排除自己在订阅一个其他的视频

                [strongSelf.mvideo subscribe:camer.id];//订阅
                [strongSelf.mvideo attachRenderWithDeviceId:camer.id render:strongSelf.bigRender];//渲染
                return ;
            }
        }];
    }
    if (self.mscreen.publishedScreens.count>0) {
       AVDCamera *cam = self.mscreen.publishedScreens.firstObject;
        [self.mscreen detachRenderWithRender:self.bigRender];
        [self.mscreen subscribe:cam.id];//订阅
        [self.mscreen attachRenderWithDeviceId:cam.id render:self.bigRender];//渲染
       
    }
}

#pragma mark ROOM Delegate
//指示用户离开房间 reason == 807：服务器端报807错误，说明UDP不通或UDP连接超时   reason == 804：同一个userid加会， 把前一个人踢下线 reason == 808：调用rest api接口把人踢下线reason == 809：无授权 15分钟以后强制踢人 其它：你被踢出会议室
- (void)onLeaveIndication:(AVDResult)reason fromUser:(AVDUserId)fromId{
    NSLog(@"RoomViewController, onLeaveIndication, reason:%lu", (unsigned long)reason);
}

//网络状态回调
- (void)onConnectionStatus:(enum AVDConnectionStatus)status{
    if (connectFailed == status) {//链接失败 离开房间
        NSLog(@"断线失败");
//        [self.mscreen stopRecord];
        [self closeRoom:nil];
    }else if (connecting == status){//to do 正在重连 hud提示或者其他操作。。按自己产品设计来
        NSLog(@"断线重连中");
//        [self.mscreen stopRecord];
    }else if (connected == status){//c重连成功
        NSLog(@"断线重连成功");

//        [self.mscreen proceedRecord];
//        [self.mscreen updateScreenData:_localScreenId level:0 description:@"{\"video_name\":\"ios屏幕\"}"];
//        [self.mvideo updateCameraData:_localVideoId level:0 description:@"{\"video_name\":\"ios9610\"}"];

    }
}

#pragma mark --video delegate 发布视频时回调这些方法
//参会者摄像头状态回调
- (void) onCameraStatusNotify:(enum AVDDeviceStatus)status deviceId:(AVDDeviceId)fromId {
    NSLog(@"VideosView, onCameraStatusNotify, status:%u, from:%@", status, fromId);
    if ([self.mvideo isSelfDevice:fromId] || ds_published != status) {
        return ;
    }

}


//房间中所有参会者发布视频都会走这个回调
- (void) onPublishCameraNotify:(AVDCamera*)item {
    NSLog(@"VideosView, onPublishCameraNotify, camera:%@", item.id);
    if ([self.mvideo isSelfDevice:item.id]) {
        NSLog(@"onpublishCameraNotify is Self camera");
    }else {
        [self.mvideo detachRenderWithRender:self.bigRender];
        AVDResult ret = [self.mvideo subscribe:item.id];
        [self.mvideo attachRenderWithDeviceId:item.id render:self.bigRender];
    }

}

//房间中所有参会者取消发布视频都会走这个回调
- (void) onUnpublishCameraNotify:(AVDCamera*)item {
    NSLog(@"VideosView, onUnpublishCameraNotify, camera:%@", item.id);
    if ([self.mvideo isSelfDevice:item.id]) {
        NSLog(@"onUnpublishCameraNotify is Self camera");
        return ;
    }
    [self.mvideo unsubscribe:item.id];
    [self.mvideo detachRenderWithRender:self.bigRender];
 
}

- (void)onPublishScreenNotify:(AVDVideoDevice *)screen{
    NSString *userid =  [self.mscreen getOwnerId:screen.id];
    NSLog(@"selfUserid = %@ xxxself = %@",userid,self.mmanager.selfUser.userId);
    
    if ([self.mscreen isSelfDevice:screen.id]) {
        AVDMediaStats *stats = [self.room getMediaStats:screen.id];
        NSLog(@"视频的宽 = %ld 高 = %ld",stats.frame_width,stats.frame_height);
//        [self.mscreen setScreenBitrate:screen.id min:800*1000 max:1000*2000];
//        [self.mscreen updateScreenData:screen.id level:0 description:@"{\"video_name\":\"ios屏幕\"}"];
        _localScreenId = screen.id;
        return ;
    }
    [self.mscreen detachRenderWithRender:self.bigRender];
    [self.bigRender setMirror:NO];
    [self.mscreen subscribe:screen.id];
    [self.mscreen attachRenderWithDeviceId:screen.id render:self.bigRender];
}
//

- (void)onUnpublishScreenNotify:(AVDVideoDevice *)screen{
    
    [self.mscreen unsubscribe:screen.id];
    [self.mscreen detachRenderWithRender:self.bigRender];
}

#pragma mark --screen video delegate common
//摄像头订阅回调
- (void) onSubscribeResult:(AVDResult)result deviceId:(AVDDeviceId)fromId {
    NSLog(@"VideosView, onSubscribeResult, result:%lu fromId:%@", (unsigned long)result, fromId);
 

}
//取消订阅回调
- (void) onUnsubscribeResult:(AVDResult)result deviceId:(AVDDeviceId)fromId {
    NSLog(@"VideosView, onUnsubscribeResult, result:%lu fromId:%@", (unsigned long)result, fromId);
}

//自己发布本地视频回调
- (void) onPublishLocalResult:(AVDResult)result deviceId:(AVDDeviceId)fromId {
    NSLog(@"VideosView, onPublishLocalResult, result:%lu fromId:%@", (unsigned long)result, fromId);
    [self.mvideo attachRenderWithDeviceId:fromId render:self.smallRender];
    [self.mvideo setVideoBitrate:fromId min:2000*1000 max:4000*1000];
     [self.mvideo updateCameraData:fromId level:0 description:@"{\"video_name\":\"ios\"}"];
    _localVideoId = fromId;
}

//自己取消发布本地视频回调
- (void) onUnpublishLocalResult:(AVDResult)result deviceId:(AVDDeviceId)fromId {
    NSLog(@"VideosView, onUnpublishLocalResult, result:%lu fromId:%@", (unsigned long)result, fromId);
    [self.mvideo detachRenderWithRender:self.smallRender];

}

#pragma mark - 用户加会 离会回调
- (void)onUserJoinNotify:(AVDUser *)user{
    NSLog(@"onUserJoinNotify user = %@", user);  
}

- (void)onUserLeaveNotify:(AVDUser *)user{
     NSLog(@"onUserLeaveNotify user = %@", user);
}

- (void)onUserLeaveNotify:(AVDResult)reason leaveUser:(AVDUser *)user{
    NSLog(@"onUserLeaveNotify user = %@, reason = %d", user,reason);
}

#pragma mark UI Action
//
- (IBAction)closeRoom:(UIButton *)sender {
    [self removeUploaderEventMonitor];
    [self.room leave:AVD_Success];
    [self.room destory];
    self.room = nil;
    [self dismissViewControllerAnimated:YES completion:^{
    }];
}


- (IBAction)toolBtnClicked:(UIButton *)sender {
    if ([sender.currentTitle isEqualToString:@"摄像头"]) {
        sender.selected = !sender.selected;
        NSLog(@"isSelected = %d",sender.selected);
        if (sender.selected) {
            [self.mvideo unpublishLocalCamera];
        }else{
            [self.mvideo publishLocalCamera];
        }
    }else if ([sender.currentTitle isEqualToString:@"麦克风"]){
        sender.selected = !sender.selected;
        if (sender.selected) {
            [self.maudio closeMicrophone];
        }else{
            [self.maudio openMicrophone];
        }
    }else if ([sender.currentTitle isEqualToString:@"切换"]){//demo没有记录当前状态
        [self.mvideo switchToLocalCamera];

    }else if ([sender.currentTitle isEqualToString:@"白板"]){//
        if (self.mwhiteboard.sharedBoards.count) {
             [N2MSetting showAlertViewWithTitle:@"警告" message:@"当前已经存在其他白板" delegate:self cancelButtonTitle:@"知道了"];
            return;
        }
        [self sharedBoardInfo:self.boradView];
    }else if ([sender.currentTitle isEqualToString:@"停止"]){//
        if ([self isSelfShareBoard]) {//是自己共享的才调用close
            [self.mwhiteboard removeBoard:self.boradInfo.boardId];
            self.boradView.hidden = YES;
            [self.mwhiteboard dettachView:self.boradView  boardId:self.boradInfo.boardId];
        }
       
    }
}

//共享
- (IBAction)startRecord:(UIButton *)sender {
    sender.selected = !sender.selected;
    //sender.selected ?[self.mscreen publishScreen:screen_resolution_1080p fps:15]: [self.mscreen unpublishScreen];
    if (sender.selected) {
        if (@available(iOS 12, *)) {//ios12 系统级别录制
                        if (!self.broadPickerView) {
                            self.broadPickerView = [[RPSystemBroadcastPickerView alloc] initWithFrame:CGRectMake(-100,-100, 100, 100)];
                            self.broadPickerView.preferredExtension = @"tee.sysScreenDemo.boardExtenion";
                            self.broadPickerView.showsMicrophoneButton = NO;
                            [self.view addSubview:self.broadPickerView];
                        }
                        for (UIView *subView in self.broadPickerView.subviews) {
                            if ([subView isKindOfClass:[UIButton class]]) {
                                [(UIButton *)subView sendActionsForControlEvents:UIControlEventAllEvents];
                                break;
                            }
                        }
        }else{
            NSLog(@"ios12以下暂不支持系统级别的录制");
        }
        
    }else{
        //通知extension停止录制
        CFNotificationCenterRef notification = CFNotificationCenterGetDarwinNotifyCenter ();
        CFNotificationCenterPostNotification(notification, CFSTR("broadcastStop"), NULL,NULL, YES);
        [self.mscreen unpublishScreen];
    }
}
//透明按钮
- (IBAction)cleanBoardImg:(UIButton *)sender {
    [self.boradView updateBackgroundImg:nil];
//    [self.boradView updateBackgroundColor:[UIColor clearColor]];
}

//冻屏按钮 
- (IBAction)updateBoardImg:(UIButton *)sender {
    if ([self.boradInfo.userId isEqualToString:self.mmanager.selfUser.userId]) {//自己的白板才可以更新白板背景图
        UIImage *img =  [self.bigRender captureRenderImage:100.0f];
        NSString *filePath = [self saveImg:img];
        [self.mwhiteboard setBackgroundImage:self.boradInfo.boardId filePath:filePath];
        [self.boradView updateBackgroundImg:img];
    }else {
         [N2MSetting showAlertViewWithTitle:@"警告" message:@"你不是白板创建者不允许更新背景图" delegate:self cancelButtonTitle:@"知道了"];
    }
   
}

//听筒
- (IBAction)stopRecord:(UIButton *)sender {
    //0 扬声器 1听筒
    sender.selected = !sender.selected;
    [AVDAudio setSpeakerMode:sender.selected?SM_Handfree:SM_Receiver];
   

}
- (IBAction)screenSwitch:(UIButton *)sender {
    [self.mscreen stopRecord];
    sender.selected = !sender.selected;
    [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:sender.selected?UIInterfaceOrientationLandscapeRight:UIDeviceOrientationPortrait] forKey:@"orientation"];
//     [self presentViewController:[ViewController new] animated:YES completion:nil];
//    [self.presentedViewController dismissViewControllerAnimated:YES completion:nil];

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//        [self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
        //2.0秒后追加任务代码到主队列，并开始执行
        //打印当前线程
        [self.mscreen proceedRecord];
        NSLog(@"after---%@",[NSThread currentThread]);
    });
}

#pragma mark - 白板

//获取自己当前是否已经共享白板
- (AVDWhiteboardInfo *)sharedBoardInfo:(UIView *)view{
    //NSLog(@"当前共享的白板列表 %@",self.mboard.publishedBoards);
    __block BOOL isShare = NO;
    __block AVDWhiteboardInfo *boardInfo = nil;
    AVDResult creatResult;
    [self.mwhiteboard.publishedBoards enumerateObjectsUsingBlock:^(AVDWhiteboardInfo *obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if ([obj.userId isEqualToString:self.mmanager.selfUser.userId]) {
            isShare = YES;
            boardInfo = obj;
        }
    }];
    if (!isShare) {
        boardInfo = [[AVDWhiteboardInfo alloc] init];
        boardInfo.boardId = [[NSUUID UUID] UUIDString];
        boardInfo.userId = self.mmanager.selfUser.userId;
        boardInfo.width = view.frame.size.width;
        boardInfo.height = view.frame.size.height;
        boardInfo.color = [UIColor clearColor];//[self colorWithHexString:@"#ffffff" alpha:1];
        creatResult =  [self.mwhiteboard createBoard:boardInfo];
    }
    AVDResult result = [self.mwhiteboard shareBoard:boardInfo.boardId];
    [self.mwhiteboard attachView:view boardInfo:boardInfo];
    view.hidden = NO;
    self.boradInfo = boardInfo;
    return boardInfo;
}

- (UIColor *)colorWithHexString:(NSString *)color alpha:(CGFloat)alpha{
    //删除字符串中的空格
    NSString *cString = [[color stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString];
    // String should be 6 or 8 characters
    if ([cString length] < 6) {
        return [UIColor clearColor];
    }
    // strip 0X if it appears
    //如果是0x开头的，那么截取字符串，字符串从索引为2的位置开始，一直到末尾
    if ([cString hasPrefix:@"0X"]) {
        cString = [cString substringFromIndex:2];
    }
    //如果是#开头的，那么截取字符串，字符串从索引为1的位置开始，一直到末尾
    if ([cString hasPrefix:@"#"]) {
        cString = [cString substringFromIndex:1];
    }
    if ([cString length] != 6) {
        return [UIColor clearColor];
    }
    // Separate into r, g, b substrings
    NSRange range;
    range.location = 0;
    range.length = 2;
    //r
    NSString *rString = [cString substringWithRange:range];
    //g
    range.location = 2;
    NSString *gString = [cString substringWithRange:range];
    //b
    range.location = 4;
    NSString *bString = [cString substringWithRange:range];
    // Scan values
    unsigned int r, g, b;
    [[NSScanner scannerWithString:rString] scanHexInt:&r];
    [[NSScanner scannerWithString:gString] scanHexInt:&g];
    [[NSScanner scannerWithString:bString] scanHexInt:&b];
    return [UIColor colorWithRed:((float)r / 255.0f) green:((float)g / 255.0f) blue:((float)b / 255.0f) alpha:alpha];
}

- (BOOL)isSelfShareBoard{
    __block BOOL isSelf = NO;
    [self.mwhiteboard.sharedBoards enumerateObjectsUsingBlock:^(AVDWhiteboardInfo *obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if ([obj.userId isEqualToString:self.mmanager.selfUser.userId]) {
            isSelf = YES;
        }
    }];
    return isSelf;
}

- (void)onCreateBoardNotify:(AVDWhiteboardInfo *)whiteboardInfo{
    self.boradInfo = whiteboardInfo;
    NSLog(@"board = 1%@",self.boradInfo);
}

- (void)onRemoveBoardNotify:(AVDBoardId)whiteboardId{
    NSLog(@"board = 2");
    if ([self.boradInfo.boardId isEqualToString:whiteboardId]) {
        self.boradView.hidden = YES;
        [self.boradView updateBackgroundImg:nil];
        [self.mwhiteboard dettachView:self.boradView boardId:whiteboardId];
    }
}

- (void)onShareBoardNotify:(AVDWhiteboardInfo *)whiteboardInfo{
    NSLog(@"board = 3");
    self.boradView.hidden = NO;
    self.boradInfo = whiteboardInfo;
    [self.mwhiteboard attachView:self.boradView boardInfo:self.boradInfo];
}

- (void)onCloseBoardNotify:(AVDBoardId)whiteboardId{
    NSLog(@"board = 4");
    self.boradView.hidden = YES;
    if ([self.boradInfo.boardId isEqualToString:whiteboardId]) {
        self.boradView.hidden = YES;
        [self.boradView updateBackgroundImg:nil];
        [self.mwhiteboard dettachView:self.boradView boardId:whiteboardId];
    }
}

- (void)onUpdateBoardNotify:(AVDWhiteboardInfo *)whiteboardInfo{
    if (whiteboardInfo.bgUrl) {
        NSURL *imgURL = [NSURL URLWithString:whiteboardInfo.bgUrl];
        NSData *imageData = [NSData dataWithContentsOfURL:imgURL];
        UIImage *image = [UIImage imageWithData:imageData];
        NSLog(@"远端白板背景图更新 = %@",image);
        [self.boradView updateBackgroundImg:image];
    }
}

- (AVDCamera *)getPubCarmeraByUerId:(NSString *)userId{
    AVDCamera *tempCam = nil;
    for (AVDCamera *cam in self.mvideo.publishedCameras) {
        AVDUserId uid = [self.mvideo getOwnerId:cam.id];
        if ([userId isEqualToString:uid]) {
            tempCam = cam;
        }
    }
    return tempCam;
}

- (void)showSDKLog{
//    [self presentViewController:[ViewController new] animated:YES completion:nil];
  
}

- (void)uiChangeNotifi:(NSNotification *)noti{
//    [self.mscreen stopRecord];
}

#pragma mark scren callback
- (void)publishScreenCallback:(NSNotification *)noti{
    NSError *err = noti.userInfo[@"error"];
    if (err) {
        NSLog(@"rprecord start fail == %@",err.description);
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//            [self.mscreen proceedRecord];
        });
    }
}

- (void)stopScreenErrCallback:(NSNotification *)noti{
    NSError *err = noti.userInfo[@"error"];
    if (err) {
        NSLog(@"rprecord stop fail == %@",err.description);
//        [self.mscreen stopRecord];
    }
}

- (void)willEnterForegroud:(NSNotification *)noti{
    NSLog(@"[RPScreenRecorder sharedRecorder].recording = %d",[RPScreenRecorder sharedRecorder].recording);
}

- (NSString *)getNowTimeStamp {
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init] ;
    [formatter setDateStyle:NSDateFormatterMediumStyle];
    [formatter setTimeStyle:NSDateFormatterShortStyle];
    [formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"]; // 设置想要的格式，hh与HH的区别:分别表示12小时制,24小时制
    //设置时区,这一点对时间的处理很重要
    NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Shanghai"];
    [formatter setTimeZone:timeZone];
    NSDate *dateNow = [NSDate date];
    NSString *timeStamp = [NSString stringWithFormat:@"%ld", (long)[dateNow timeIntervalSince1970]];
    return timeStamp;
    
}

- (void)onPublicMessage:(AVDMessage *)message{
    NSLog(@"rev msg = %@",message.message);
    if (![message.message containsString:@"|"]) {
        return;
    }
    NSArray  * array= [message.message componentsSeparatedByString:@"|"];
//    [self.bigRender setRenderZone:CGRectMake([array[0] integerValue], [array[1] integerValue], [array[2] integerValue], [array[3] integerValue])];
}

- (NSString *)saveImg:(UIImage *)img{
    NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    path = [path stringByAppendingString:[NSString stringWithFormat:@"/images"]];
    // 判断文件夹是否存在，如果不存在，则创建
    if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
        [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
    } else {
        //NSLog(@"FileDir is exists.");
    }
    NSString *imageFilePath = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"/%@@2x.png",@"boardBg"]];
    [UIImageJPEGRepresentation(img, 1) writeToFile:imageFilePath  atomically:YES];
    return imageFilePath;
}

- (void)onStreamKeepAliveTimeoutNotify:(NSString *)userId userName:(NSString *)userName mediaType:(NSInteger)type deviceId:(NSString *)deviceId ssrc:(NSInteger)ssrc{
    NSString *msg = [NSString stringWithFormat:@"流发布超时 name= %@ type = %d",userName,type];
    [N2MSetting showAlertViewWithTitle:@"警告" message:msg delegate:self cancelButtonTitle:@"知道了"];
}

#pragma mark --- 注册extension通知
- (void)addUploaderEventMonitor {
    NSLog(@"addUploaderEventMonitor");
    [self registerForNotificationsWithIdentifier:@"broadcastStartedWithSetupInfo"];
    [self registerForNotificationsWithIdentifier:@"broadcastFinished"];
    //这里同时注册了纷发消息的通知，在宿主App中使用
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(broadcastInfo:) name:@"ScreenHoleNotificationName" object:nil];
}

//注册进程间通知
- (void)registerForNotificationsWithIdentifier:(nullable NSString *)identifier {
    CFNotificationCenterRef const center = CFNotificationCenterGetDarwinNotifyCenter();
    CFStringRef str = (__bridge CFStringRef)identifier;
    CFNotificationCenterAddObserver(center,
                                    (__bridge const void *)(self),
                                    MyHoleNotificationCallback,
                                    str,
                                    NULL,
                                    CFNotificationSuspensionBehaviorDeliverImmediately);
}

//进程间通知回调处理并且分发宿主app中通知
void MyHoleNotificationCallback(CFNotificationCenterRef center,
                                void * observer,
                                CFStringRef name,
                                void const * object,
                                CFDictionaryRef userInfo) {
    NSString *identifier = (__bridge NSString *)name;
    NSDictionary *notiUserInfo = @{@"identifier":identifier};
    [[NSNotificationCenter defaultCenter] postNotificationName:@"ScreenHoleNotificationName"                                                   object:nil userInfo:notiUserInfo];
}
//宿主app通知回调
- (void)broadcastInfo:(NSNotification *)noti {
    NSDictionary *userInfo = noti.userInfo;
    NSString *identifier = userInfo[@"identifier"];
    if ([identifier isEqualToString:@"broadcastStartedWithSetupInfo"]) {//extension开始屏幕直播
        NSLog(@"broadcastStartedWithSetupInfo");
        if (@available(iOS 12.0, *)) {
            [self.mscreen publishSystemScreen:screen_resolution_1080p fps:10];//宿主app发布屏幕共享
            
        } else {
            // Fallback on earlier versions
        }
    }
    if ([identifier isEqualToString:@"broadcastFinished"]) {//extension停止屏幕直播
        NSLog(@"broadcastFinished");
        [self.mscreen unpublishScreen];////宿主app停止屏幕共享
    }
}

//移除进程间通知和宿主app内通知
- (void)removeUploaderEventMonitor {
    NSLog(@"removeUploaderEventMonitor");
    [self unregisterForNotificationsWithIdentifier:@"broadcastStartedWithSetupInfo"];
    [self unregisterForNotificationsWithIdentifier:@"broadcastPaused"];
    [self unregisterForNotificationsWithIdentifier:@"broadcastFinished"];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"ScreenHoleNotificationName" object:nil];
}

- (void)unregisterForNotificationsWithIdentifier:(NSString *)identifier{
    CFNotificationCenterRef const center = CFNotificationCenterGetDarwinNotifyCenter();
    CFStringRef str = (__bridge CFStringRef)identifier;
    CFNotificationCenterRemoveObserver(center, (__bridge const void *)(self), str, NULL);
}


@end
